using System.Collections;
using System.Windows.Controls;
using ShadeTree.Binding.Elements;
using ShadeTree.Binding.Lists;

namespace ShadeTree.Binding.WPF
{
    public class PicklistElement : BoundScreenElement<ComboBox, object>, IListElement
    {
        private IPicklist _list = new NulloPicklist();

        public PicklistElement(Accessor accessor, ComboBox control) : base(accessor, control)
        {
            setup(control);
        }

        public IList Items
        {
            get
            {
                return new ArrayList(BoundControl.Items);
            }
        }

        public string Display
        {
            get { return _list.GetDisplay(BoundControl); }
        }

        #region IListElement Members

        public void FillWithList(IPicklist list)
        {
            BoundControl.SelectionChanged -= control_SelectionChanged;
            BoundControl.SelectedValue = null;
            BoundControl.SelectionChanged += control_SelectionChanged;

            list.Fill(BoundControl);
            _list = list;
        }

        public void FillWithList(string[] strings)
        {
            var list = new Picklist<string>(strings);
            FillWithList(list);
        }

        public string DisplayValue
        {
            get { return _list.GetDisplay(BoundControl.SelectedItem); }
        }

        public IList GetListOfItems()
        {
            return Items;
        }

        public void SelectByDisplay(string display)
        {
            _list.SelectForDisplay(BoundControl, display);
            
            // The WPF ComboBox doesn't fire the SelectionChanged event
            // when the value is changed programatically.  Thanks, MS.
            elementValueChanged();
        }

        #endregion

        protected void setup(ComboBox control)
        {
            control.SelectionChanged += control_SelectionChanged;
        }

        private void control_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            elementValueChanged();
        }

        protected override void tearDown()
        {
            BoundControl.SelectionChanged -= control_SelectionChanged;
        }


        protected override object getValueFromControl()
        {
            return _list.GetValue(BoundControl.SelectedItem);
        }

        protected override void resetControl(object originalValue)
        {
            _list.SetValue(BoundControl, originalValue);
        }

        public void SelectDisplay(string display)
        {
            _list.SelectForDisplay(BoundControl, display);
        }


        public bool HasSelection()
        {
            return BoundControl.SelectedValue != null;
        }


        public override void SetDefaults()
        {
            if (BoundControl.Items.Count == 1)
            {
                resetControl(BoundControl.Items[0]);
            }
            else
            {
                base.SetDefaults();
            }
        }
    }
}